#include "SessionModel.h"
#include <algorithm>
#include "ChessShuffle.h"
#include "Utils.h"

SessionModel::SessionModel()
    : m_sessionCunt(0)
    , m_hostPlayerPs(Postion::DEFAULT)
    , m_userPlayerPs(Postion::DEFAULT)

    , m_turnerPlayerPs(Postion::DEFAULT)
    , m_dispatchOffset(0)
    , m_gangOffset(0)
{
}

SessionModel::~SessionModel()
{
    clearData();
}

bool SessionModel::addSessionPlayer(Postion ps, const SessionPlayer& sessionPlayer)
{
    if (m_sessionPlayerArry[ps].id.empty())
    {
        m_sessionPlayerArry[ps] = sessionPlayer;
        m_sessionPlayerArry[ps].postion = ps;
        return true;
    }
    return false;
}

void SessionModel::removeSessionPlayer(Postion ps)
{
    m_sessionPlayerArry[ps].id = "";
}

SessionPlayer* SessionModel::getSessionPlayer()
{
    return m_sessionPlayerArry;
}

const SessionPlayer& SessionModel::getSessionPlayerByPs(Postion ps) const
{
    return m_sessionPlayerArry[ps];
}

void SessionModel::setHostPlayer(Postion ps)
{
    m_hostPlayerPs = ps;
    for (size_t i = 0; i < SessionEnum::MAX_PLAYER_SIZE; i++)
    {
        if (i == ps)
        {
            m_sessionPlayerArry[i].role = RoleType::HOST;
        }
        else
        {
            m_sessionPlayerArry[i].role = RoleType::CLIENT;
        }
    }
}

const SessionPlayer& SessionModel::getHostPlayerPs() const
{
    return m_sessionPlayerArry[m_hostPlayerPs];
}

void SessionModel::setUserPlayer(Postion ps)
{
    m_userPlayerPs = ps;
}

const SessionPlayer& SessionModel::getUserPlayerPs() const
{
    return m_sessionPlayerArry[m_userPlayerPs];
}

void SessionModel::clearData()
{
    for (size_t i = 0; i < SessionEnum::MAX_PLAYER_SIZE; i++)
    {
        m_sessionPlayerArry[i] = SessionPlayer();
    }
    m_sessionCunt = 0;
    m_hostPlayerPs = Postion::DEFAULT;
    m_userPlayerPs = Postion::DEFAULT;
    clearSessionData();
}

void SessionModel::shuffleChess(short maxChessCunt)
{
    m_sessionCunt++;
    clearSessionData();
    m_shuffleChess = ChessShuffle::getShuffleChessArry(maxChessCunt);
    m_dispatchOffset = 0;
    m_gangOffset = m_shuffleChess.size() - 1;
}

const std::vector<Chess>& SessionModel::getShuffleChess() const
{
    return m_shuffleChess;
}

void SessionModel::addPlayerChess(Postion ps, const Chess& chess)
{
    m_handleChessArry[ps].push_back(chess);
}

void SessionModel::sortPlayerChess(Postion ps)
{
    std::sort(m_handleChessArry[ps].begin(), m_handleChessArry[ps].end());
}

void SessionModel::removePlayerChess(Postion ps, const Chess& chess)
{
    auto iterFind = std::find(m_handleChessArry[ps].begin(), m_handleChessArry[ps].end(), chess);
    if (iterFind != m_handleChessArry[ps].end())
    {
        m_handleChessArry[ps].erase(iterFind);
    }
}

void SessionModel::removePlayerChessByWeaveChess(Postion ps, const KindChess& weaveChess)
{
    for (size_t i = 0; i < weaveChess.item.size(); i++)
    {
        auto iterFind = std::find(m_handleChessArry[ps].begin(), m_handleChessArry[ps].end(), weaveChess.item.at(i));
        if (iterFind != m_handleChessArry[ps].end())
        {
            m_handleChessArry[ps].erase(iterFind);
        }
    }
}

const std::vector<Chess>& SessionModel::getHandleChessByPs(Postion ps)
{
    return m_handleChessArry[ps];
}

void SessionModel::addOutputChess(Postion ps, const Chess& chess)
{
    m_outputChessArry[ps].push_back(chess);
}

void SessionModel::removeOutputChess(Postion ps, const Chess& chess)
{
    auto iterFind = std::find(m_outputChessArry[ps].begin(), m_outputChessArry[ps].end(), chess);
    if (iterFind != m_outputChessArry[ps].end())
    {
        m_outputChessArry[ps].erase(iterFind);
    }
}

const std::vector<Chess>& SessionModel::getOutputChessByPs(Postion ps)
{
    return m_outputChessArry[ps];
}

void SessionModel::addWeaveChess(Postion ps, const KindChess& kindChess)
{
    m_weaveChessArry[ps].push_back(kindChess);
}

void SessionModel::updateWeave2XuGang(Postion ps, const Chess& chess)
{
    for (size_t i = 0; i < m_weaveChessArry[ps].size(); i++)
    {
        if ((m_weaveChessArry[ps].at(i).type == ChessStatus::PENG) &&
            (m_weaveChessArry[ps].at(i).item.at(0) == chess))
        {
            m_weaveChessArry[ps].at(i).type = ChessStatus::XUGANG;
            m_weaveChessArry[ps].at(i).item.push_back(chess);
        }
    }
}

const std::vector<KindChess>& SessionModel::getWeaveChessByPs(Postion ps)
{
    return m_weaveChessArry[ps];
}

void SessionModel::setShowOffsetPair(ShowOffsetPair* showOffset)
{
    m_showOffsetPair[0] = showOffset[0];
    m_showOffsetPair[1] = showOffset[1];
    m_showOffsetPair[2] = showOffset[2];
    m_showOffsetPair[3] = showOffset[3];
}

const ShowOffsetPair* SessionModel::getShowOffsetPair() const
{
    return m_showOffsetPair;
}

bool SessionModel::isChessOver() const
{
    return (m_dispatchOffset <= m_gangOffset);
}

Postion SessionModel::getTurnerPostion() const
{
    return m_turnerPlayerPs;
}

void SessionModel::setTurnerPostion(Postion ps)
{
    m_turnerPlayerPs = ps;
}

bool SessionModel::dispatchChess(Chess& newChess)
{
    if (!isChessOver())
    {
        return false;
    }
    newChess = m_shuffleChess[m_dispatchOffset];
    ++m_dispatchOffset;
    return true;
}

bool SessionModel::dispatchGangChess(Chess& newChess)
{
    if (!isChessOver())
    {
        return false;
    }
    newChess = m_shuffleChess[m_gangOffset];
    --m_gangOffset;
    return true;
}

short SessionModel::getSessionCunt() const
{
    return m_sessionCunt;
}

size_t SessionModel::getDispatchOffset() const
{
    return m_dispatchOffset;
}

size_t SessionModel::getGangOffset() const
{
    return m_gangOffset;
}

void SessionModel::clearSessionData()
{
    for (size_t i = 0; i < SessionEnum::MAX_PLAYER_SIZE; i++)
    {
        m_handleChessArry[i].clear();
        m_outputChessArry[i].clear();
        m_weaveChessArry[i].clear();
        m_showOffsetPair[i] = ShowOffsetPair();
    }
    m_shuffleChess.clear();

    m_turnerPlayerPs = Postion::DEFAULT;
    m_dispatchOffset = 0;
    m_gangOffset = 0;
}